package com.xplay.xpocker.room.mahjong;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xplay.xpocker.constant.ConstantDict;
import com.xplay.xpocker.constant.MessageNoticeEnum;
import com.xplay.xpocker.dvo.AbstractRoom;
import com.xplay.xpocker.dvo.GameRoomStruct;
import com.xplay.xpocker.dvo.GameRuMahjongUserState;
import com.xplay.xpocker.entity.*;
import com.xplay.xpocker.room.IarMessageTL;
import com.xplay.xpocker.room.RoomInfoTL;
import com.xplay.xpocker.room.mahjong.constant.MKey;
import com.xplay.xpocker.room.mahjong.dto.*;
import com.xplay.xpocker.room.mahjong.settlement.SettlementInterface;
import com.xplay.xpocker.room.message.MessageContent;
import com.xplay.xpocker.room.message.MessageContentFactory;
import com.xplay.xpocker.room.message.MessageToClient;
import com.xplay.xpocker.room.message.MessageType;
import com.xplay.xpocker.service.GameHiRoomService;
import com.xplay.xpocker.service.GameRuMahjongLogsService;
import com.xplay.xpocker.service.gaming.GameRuRoomService;
import com.xplay.xpocker.util.CardUtil;
import com.xplay.xpocker.util.JacksonStringUtil;
import com.xplay.xpocker.util.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public abstract class AbstractMahjongAction {

    @Autowired
    protected MahjongActionHandler mahjongActionHandler;

    @Autowired
    protected GameRuMahjongLogsService logsService;

    @Autowired
    protected GameHiRoomService hiRoomService;

    @Autowired
    protected GameRuRoomService ruRoomService;


    /**
     * 清空房间信息
     * 洗牌 发牌
     */
    protected final void dealCards() {
        MahjongRoomInfo gameInfo = getRoomInfo().getGameInfo();
        AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo = getRoomInfo();
        // 清理用户所有信息
        for (GameRuMahjongUserState user : roomInfo.getGameInfo().getAllUser()) {
            user.setCompleted(null);
            user.setSwapUserId(null);
            user.setSwapCardOut(null);
            user.setSwapCardIn(null);
            user.setBeforeCompleted(null);
            user.setCompletedData(null);
            user.setHandCards(null);
            user.setWin(false);
            user.setTouchCard(null);
            user.setExportCards(null);
            user.setWinCard(null);
            user.setOpenDeal(null);
            user.setFractions(null);
            user.setListen(false);
            user.setListenCards(null);
            user.setCompletedHistory(null);
        }
        // 重新洗牌
        String buildAllCardString = CardUtil.buildAllCardString();
        StringBuilder logBuilder = new StringBuilder(roomInfo.getCode()).append("\n").append("发牌信息:").append(buildAllCardString).append("\n");
        String[] diskAll = CardUtil.buildCard(buildAllCardString);
        roomInfo.setStatus(MahjongStatusEnum.GAMING.getStatus());
        for (GameRuMahjongUserState otherUser : gameInfo.getAllUser()) {
            int count = 13;
            // 获取13张牌
            String[] otherUserCards = CardUtil.getCard(diskAll, count);
            otherUser.setHandCards(CardUtil.joinCard(otherUserCards));
            logBuilder.append(otherUser.getBanker() ? "庄家" : "闲家").append("卡牌信息:").append(otherUser.getHandCards()).append("\n");
            // 删掉13张
            diskAll = CardUtil.delCard(diskAll, count);
            if (otherUser.getBanker()) {
                // 获取一张
                otherUser.setTouchCard(Integer.valueOf(CardUtil.getCard(diskAll, 1)[0]));
                // 删掉1张
                diskAll = CardUtil.delCard(diskAll, 1);
            }
        }
        // 剩余的牌设置回去
        String residueCards = CardUtil.joinCard(diskAll);
        gameInfo.setCards(residueCards);
        logBuilder.append("剩余的卡牌:").append(residueCards);
        log.debug(logBuilder.toString());
    }

    /**
     * 从桌面拿到最后一张牌
     */

    protected final String nextCard() {
        MahjongRoomInfo gameInfo = getRoomInfo().getGameInfo();
        String[] diskAllCard = CardUtil.buildCard(gameInfo.getCards());
        if (diskAllCard.length == 0) {
            return null;
        }
        String lastCard = diskAllCard[diskAllCard.length - 1];
        gameInfo.setCards(CardUtil.joinCard(CardUtil.delCard(diskAllCard, 1)));
        gameInfo.printAllCard(lastCard);
        return lastCard;
    }


    /**
     * 获取下一个没有胡牌的用户
     *
     * @param seq
     * @return
     */

    protected final GameRuMahjongUserState nextUser(Integer seq) {
        AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo = getRoomInfo();
        if (seq == null) {
            seq = roomInfo.getGameInfo().getCurrentUser().getSeq();
        }
        GameRuMahjongUserState nextUser = null;
        Integer nextUserSeq = seq + 1;
        while (nextUser == null) {
            if (nextUserSeq > roomInfo.getRule().getUserCount()) {
                nextUserSeq = 1;
            }
            for (GameRuMahjongUserState otherUser : roomInfo.getGameInfo().getAllUser()) {
                // 如果找到这个人胡牌了 序列加1
                if (otherUser.getSeq().equals(nextUserSeq) && otherUser.isWin()) {
                    nextUserSeq++;
                    break;
                    //没有胡牌直接返回
                } else if (otherUser.getSeq().equals(nextUserSeq) && !otherUser.isWin()) {
                    nextUser = otherUser;
                    break;
                }
            }
        }
        return nextUser;
    }

    /**
     * 按照序号获取用户
     *
     * @return
     */

    protected final GameRuMahjongUserState getBanker() {
        AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo = getRoomInfo();
        for (GameRuMahjongUserState user : roomInfo.getGameInfo().getAllUser()) {
            if (user.getBanker()) {
                return user;
            }
        }
        return roomInfo.getGameInfo().getOtherUsers().get(0);
    }

    /**
     * @param uid
     * @return
     */

    protected final List<GameRuMahjongUserState> getOtherUserByCurrent(BigDecimal uid) {
        AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo = getRoomInfo();
        if (uid == null) {
            return roomInfo.getGameInfo().getOtherUsers();
        }
        List<GameRuMahjongUserState> result = new ArrayList<>();
        for (GameRuMahjongUserState user : roomInfo.getGameInfo().getAllUser()) {
            if (!user.getUserId().equals(uid)) {
                result.add(user);
            }
        }
        return result;
    }


    /**
     * @param uid
     * @return
     */

    protected final List<GameRuMahjongUserState> getOtherUserNotWinByCurrent(BigDecimal uid) {
        List<GameRuMahjongUserState> otherUserByCurrent = getOtherUserByCurrent(uid);
        return otherUserByCurrent.stream().filter(item -> !item.isWin()).collect(Collectors.toList());
    }

    /**
     * 获取所有胡牌用户
     *
     * @return
     */

    protected final List<GameRuMahjongUserState> getAllWinUser() {
        return getRoomInfo().getGameInfo().getAllUser().stream().filter(GameRuMahjongUser::isWin).collect(Collectors.toList());
    }

    /**
     * 设置指定人为庄家
     *
     * @param roomInfo
     * @param uid
     */

    protected final void switchBanker(AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo, BigDecimal uid) {
        for (GameRuMahjongUserState userState : roomInfo.getGameInfo().getAllUser()) {
            userState.setBanker(userState.getUserId().equals(uid));
        }

    }


    /**
     * 按照序号获取用户
     *
     * @param seq
     * @return
     */

    protected final GameRuMahjongUserState getUserByUidOrSeq(BigDecimal uid, Integer seq) {
        AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo = getRoomInfo();
        if (seq == null && uid == null) {
            return roomInfo.getGameInfo().getOtherUsers().get(0);
        }
        for (GameRuMahjongUserState user : roomInfo.getGameInfo().getAllUser()) {
            if (user.getSeq().equals(seq) || user.getUserId().equals(uid)) {
                return user;
            }
        }
        return roomInfo.getGameInfo().getOtherUsers().get(0);
    }

    /**
     * 指定发给 谁
     * <p>
     * 这里会产生  事件数组
     * 1. 摸牌   摸牌延迟  200/ms
     * 2. 刷新用户的action
     *
     * @param seq  指定人 如果不指定  默认当前操作人
     * @param next 是否取指定人的下一个
     */

    protected final void dealCard(Integer seq, boolean next) {
        AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo = getRoomInfo();
        // 这里要发四条消息..... 摸牌事件人应该能明确拿到摸什么牌
        GameRuMahjongUserState nextUser = null;
        if (seq == null) {
            seq = roomInfo.getGameInfo().getCurrentUser().getSeq();
        }
        nextUser = getUserByUidOrSeq(null, seq);
        if (next) {
            nextUser = nextUser(seq);
        }
        // 获取下一张牌
        String cardStr = nextCard();
        if (ObjectUtils.isEmpty(cardStr)) {
            // 没有可发牌 游戏结算.....
            nextGaming();
            return;
        }
        Integer nextCard = Integer.valueOf(cardStr);
        nextUser.setTouchCard(nextCard);
        GameRuMahjongLogs.GameRuMahjongLogsBuilder logsBuilder = GameRuMahjongLogs.builder().type(ConstantDict.MahjongLogType.ROOM).action(MahjongActionEnum.TOUCH.getAction()).roomId(roomInfo.getId()).sourceUserId(nextUser.getUserId()).cardCode(nextCard);
        RoomInfoTL.addLog(logsBuilder.build());
        AbstractIsolationEventStrategy.getSettlementStrategy(roomInfo.getType()).dealCardActionCheck(nextUser, nextCard, roomInfo);
    }

    /**
     * 群发更新房间信息
     */
    protected final void notifyUpdateRoom() {
        String code = getRoomInfo().getCode();
        MessageContent<MahjongMessage> messageContent = new MessageContent<>(MessageType.ACTION.getType(), MahjongMessage.Builder.builder().type(MahjongActionEnum.REFRESH.getAction()).build());
        messageContent.setRoomCode(code);
        messageContent.setMnEnum(MessageNoticeEnum.ALL);
        RoomInfoTL.addMessageToClient(messageContent);
    }

    protected final void cleanUserAction(String roomCode, BigDecimal uid) {
        MessageContent<MahjongMessage> messageContent = new MessageContent<>(MessageType.ACTION.getType(), MahjongMessage.Builder.builder().exeActionUid(uid).type(MahjongActionEnum.REFRESH_ACTION.getAction()).build());
        messageContent.setRoomCode(roomCode);
        messageContent.setMnEnum(MessageNoticeEnum.CURRENT);
        messageContent.setMessageToUid(uid);
        RoomInfoTL.addMessageToClient(messageContent);
    }


    /**
     * 判断房间  是否存在指定的待处理行为
     *
     * @param actions
     * @return
     */
    public boolean checkWaitCompletedExistsAction(MahjongActionEnum actions) {
        return getRoomInfo().getGameInfo().getAllUser().stream().anyMatch(item -> item.checkUserExistAction(actions));
    }

    /**
     * 获取已经记录 当前需要处理的事件
     *
     * @return
     */

    protected final List<GameRuMahjongUserState> getAllCompletedData() {
        return getRoomInfo().getGameInfo().getAllUser().stream().filter(item -> item.getCompletedData() != null).collect(Collectors.toList());
    }

    /**
     * 只有在胡牌的时候调用,清理那些 碰杠
     */
    protected void cleanBMAction() {
        List<GameRuMahjongUserState> allUser = getRoomInfo().getGameInfo().getAllUser();
        for (GameRuMahjongUserState userInfo : allUser) {
            if (ObjectUtils.notEmpty(userInfo.getWaitCompleted()) && !userInfo.checkUserExistAction(MahjongActionEnum.HU)) {
                userInfo.setWaitCompleted(null);
                userInfo.setCompletedData(null);
                userInfo.setCompleted(null);
                cleanUserAction(getRoomInfo().getCode(), userInfo.getUserId());
            }
        }
    }

    /**
     * 获取还有多少个用户没有胡牌
     *
     * @return
     */

    protected final int notWinUserCount() {
        return (int) getRoomInfo().getGameInfo().getAllUser().stream().filter(item -> !item.isWin()).count();
    }


    /**
     * 判断其它用户有没有待处理事件
     *
     * @param actionEnums
     * @return
     */


    protected final boolean checkExistsWaitCompleted(MahjongActionEnum... actionEnums) {
        boolean result = false;
        for (GameRuMahjongUserState otherUser : getRoomInfo().getGameInfo().getAllUser()) {
            if ((actionEnums == null || actionEnums.length == 0) && ObjectUtils.notEmpty(otherUser.getWaitCompleted())) {
                result = true;
                break;
            } else if ((actionEnums != null && actionEnums.length > 0) && ObjectUtils.notEmpty(otherUser.getWaitCompleted())) {
                // 判断用户是否存在指定的事件
                result = otherUser.checkUserExistAction(actionEnums);
                if (result) {
                    break;
                }
            }
        }
        return result;
    }

    /**
     * 将所有待处理的 抽离出来
     * 循环执行
     *
     * @param roomInfo
     * @return
     */


    protected final boolean doLoadingCompleted(AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo) {
        List<GameRuMahjongUserState> allWAUser = getAllCompletedData();
        if (ObjectUtils.notEmpty(allWAUser)) {
            List<MahjongMessage> contents = new ArrayList<>();
            // 优先级判断
            boolean existsHu = allWAUser.stream().anyMatch(item -> ObjectUtils.notEmpty(item.getCompleted()) && item.getCompleted().equals(MahjongActionEnum.HU.getAction()));
            for (GameRuMahjongUserState userDTO : allWAUser) {
                MahjongMessage message = userDTO.getCompletedData();
                message.setMessageFromUserId(userDTO.getUserId());
                message.setSourceBySeq(userDTO.getSeq());
                contents.add(message);
                userDTO.cleanNextAction();
            }
            // 如果存在胡牌操作    过滤出胡牌的
            if (existsHu) {
                contents = contents.stream().filter(item -> item.getType().equals(MahjongActionEnum.HU.getAction())).collect(Collectors.toList());
            }
            contents.sort(Comparator.comparing(MahjongMessage::getSourceBySeq));
            IarMessageTL.set(contents.size());
            try {
                for (MahjongMessage content : contents) {
                    IarMessageTL.dec();
                    mahjongActionHandler.doMessage(roomInfo, content);
                }
            } finally {
                IarMessageTL.clear();
            }

        }
        return ObjectUtils.notEmpty(allWAUser);
    }

    /**
     * 设置房间状态
     *
     * @param state
     */

    protected final void setRoomState(MahjongStatusEnum state) {
        AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo = getRoomInfo();
        roomInfo.setStatus(state.getStatus());
        roomInfo.getGameInfo().setStatus(state.getStatus());
    }

    /**
     * 下一局了
     */

    protected final void nextGaming() {
        AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo = getRoomInfo();
        MahjongRoomInfo gameInfo = roomInfo.getGameInfo();






        // 存储回放相关记录
        GameRuRoomDTO gameRuRoomDTO = ruRoomService.queryRoomRuInfo(roomInfo.getCode());
        GameHiRoomDTO gameHiRoomDTO = GameRoomStruct.INSTANCE.rrToHr(gameRuRoomDTO);
        gameHiRoomDTO.setRoomId(roomInfo.getGameInfo().getRoomId());
        // 调用结算事件
        AbstractIsolationEventStrategy.getSettlementStrategy(roomInfo.getType())
                .presentSettlement(roomInfo,gameHiRoomDTO);

        hiRoomService.addHistory(gameHiRoomDTO);
        int numberGame = roomInfo.getRule().getNumberGame();
        int nextNumberGame = roomInfo.getSeveralInning() + 1;
        if (nextNumberGame > numberGame) {
            setRoomState(MahjongStatusEnum.OVER);
        } else {
            setRoomState(MahjongStatusEnum.BALANCE);
        }
        //如果游戏已经结束了，后续就没有必要执行了...
        if (!gameInfo.getStatus().equals(MahjongStatusEnum.OVER.getStatus())) {
            // 让用户准备了...
            for (GameRuMahjongUserState user : roomInfo.getGameInfo().getAllUser()) {
                user.setWaitCompleted(MahjongActionEnum.READING.getAction());
            }
        }

        // 构建消息通知
        List<MessageContent<MessageToClient>> messageList = MessageContentFactory.
                init(roomInfo.getCode(), MessageType.ACTION.getType(), null, MessageNoticeEnum.ALL)
                .multi(MKey.data, JacksonStringUtil.objectToString(roomInfo),
                        MKey.type, MahjongActionEnum.NEXT_GAMING.getAction())
                .send().getMessageList();
        RoomInfoTL.addMessageToClient(messageList, 1);
        // 清理掉运行时日志
        logsService.remove(Wrappers.<GameRuMahjongLogs>lambdaQuery().eq(GameRuMahjongLogs::getRoomId, roomInfo.getId()));

    }




    /**
     * 获取房间信息
     *
     * @return
     */

    protected final AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> getRoomInfo() {
        return RoomInfoTL.get();
    }

    /**
     * 判断用户有几门手牌
     * 用于清一色判断
     *
     * @param currentUser
     * @param card
     * @return
     */

    protected final int judgeUserCardClass(GameRuMahjongUserState currentUser, Integer card) {
        // 成都麻将 算胡牌了哟
        List<Integer> handCards = currentUser.allHandCards();
        List<Integer> copeHandCards = handCards.stream().map(Integer::new).collect(Collectors.toList());
        if (card != null) {
            copeHandCards.add(card);
        }
        if (ObjectUtils.notEmpty(currentUser.getOpenDeal())) {
            for (GameRuMahjongOpenDeal openDeal : currentUser.getOpenDeal()) {
                copeHandCards.add(openDeal.getCard());
            }
        }
        return CardUtil.judgeUserCardClass(copeHandCards);
    }

    /**
     * @param currentUser        当前加分人
     * @param exportUser         目标扣分人，如果null那么就是其余没有胡牌的人
     * @param fractionInfo       当前扣分人显示的内容
     * @param targetFractionInfo 目标扣分人显示的内容
     * @param fraction           扣取分数
     * @param roomInfo           房间
     * @param targetInter        结算有时候需要拿到用户信息重新计算比如报听
     */

    public void settlement(GameRuMahjongUserState currentUser, GameRuMahjongUserState exportUser, String fractionInfo, String targetFractionInfo, Integer fraction, AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo, SettlementInterface<GameRuMahjongUserState> targetInter) {
        if (targetFractionInfo == null || targetFractionInfo.equals("")) {
            fractionInfo = targetFractionInfo;
        }
        if (exportUser == null) {
            List<GameRuMahjongUserState> otherUserByCurrent = getOtherUserNotWinByCurrent(currentUser.getUserId());
            for (GameRuMahjongUserState targetUser : otherUserByCurrent) {
                if (targetInter != null) {
                    fraction = targetInter.point(targetUser);
                }
                GameRuMahjongFraction addFraction = new GameRuMahjongFraction();
                addFraction.setFractionInfo(fractionInfo);
                addFraction.setFraction(fraction);
                addFraction.setTargetUserId(targetUser.getUserId());
                addFraction.setSourceUserId(currentUser.getUserId());
                addFraction.setRoomId(roomInfo.getGameInfo().getRoomId());
                addFraction.setSourceUserName(currentUser.getUsername());
                addFraction.setTargetUserName(targetUser.getUsername());
                currentUser.addFraction(addFraction);
                GameRuMahjongFraction delFraction = new GameRuMahjongFraction();
                delFraction.setFractionInfo(targetFractionInfo);
                delFraction.setFraction(-fraction);
                delFraction.setTargetUserId(currentUser.getUserId());
                delFraction.setSourceUserId(targetUser.getUserId());
                delFraction.setRoomId(roomInfo.getGameInfo().getRoomId());
                delFraction.setSourceUserName(targetUser.getUsername());
                delFraction.setTargetUserName(currentUser.getUsername());
                targetUser.addFraction(delFraction);
            }
        } else {
            GameRuMahjongFraction addFraction = new GameRuMahjongFraction();
            addFraction.setFractionInfo(fractionInfo);
            addFraction.setFraction(fraction);
            addFraction.setSourceUserId(currentUser.getUserId());
            addFraction.setTargetUserId(exportUser.getUserId());
            addFraction.setRoomId(roomInfo.getGameInfo().getRoomId());
            addFraction.setSourceUserName(currentUser.getUsername());
            addFraction.setTargetUserName(exportUser.getUsername());
            currentUser.addFraction(addFraction);
            GameRuMahjongFraction delFraction = new GameRuMahjongFraction();
            delFraction.setFractionInfo(targetFractionInfo);
            delFraction.setFraction(-fraction);
            delFraction.setSourceUserId(exportUser.getUserId());
            delFraction.setTargetUserId(currentUser.getUserId());
            delFraction.setRoomId(roomInfo.getGameInfo().getRoomId());
            delFraction.setSourceUserName(exportUser.getUsername());
            delFraction.setTargetUserName(currentUser.getUsername());
            exportUser.addFraction(delFraction);
        }
    }

    /**
     * 判断庄家是否存在暗杠
     *
     * @param userDTO
     * @return
     */

    protected List<Integer> checkUserDarkBar(GameRuMahjongUserState userDTO) {
        // 庄家还有暗杠检测
        List<Integer> barCardArray = new ArrayList<>();
        //  构建 摸牌用户  胡牌 杠牌 出牌  等操作
        Map<Integer, Long> countMap = userDTO.allHandCards().stream().collect(Collectors.groupingBy(number -> number, Collectors.counting()));
        for (Map.Entry<Integer, Long> entry : countMap.entrySet()) {
            // 暗杠检测
            if (entry.getValue() > ConstantDict.Mahjong.HAND_THREE_COUNT) {
                barCardArray.add(entry.getKey());
            }
        }
        return barCardArray;
    }


    /**
     * 判断用户是否存在明杠
     *
     * @param userDTO
     * @return
     */

    protected List<Integer> checkUserMingBar(GameRuMahjongUserState userDTO) {
        return userDTO.allHandCards().stream().filter(item -> ObjectUtils.notEmpty(userDTO.getOpenDeal()) && userDTO.getOpenDeal().stream().anyMatch(child -> child.getCard().equals(item))).collect(Collectors.toList());

    }

    /**
     * 为用户添加 等待处理的事件
     *
     * @param currentUser
     * @param actions
     */


    protected void addWaitCompleted(GameRuMahjongUserState currentUser, MahjongActionEnum... actions) {
        // 构建事件体
        MahjongMessage messageBuilder = MahjongMessage.Builder.builder().exeActionUid(currentUser.getUserId()).type(MahjongActionEnum.REFRESH_ACTION.getAction()).build();
        if (actions.length > 0) {
            for (MahjongActionEnum actionEnum : actions) {
                messageBuilder.addAction(actionEnum.getAction());
            }
        }
        String waitCompleted = currentUser.getWaitCompleted();
        if (ObjectUtils.isEmpty(waitCompleted)) {
            currentUser.setWaitCompleted(messageBuilder.getActionStr());
        } else {
            for (String item : waitCompleted.split(ConstantDict.Separator.comma)) {
                messageBuilder.addAction(item);
            }
            currentUser.setWaitCompleted(messageBuilder.getActionStr());
        }
    }

    /**
     * 通知用户进行事件更新
     *
     * @param currentUser
     * @param sleep
     */

    protected void notifyUserActionUpdate(GameRuMahjongUserState currentUser, double sleep) {
        String code = getRoomInfo().getCode();
        String waitCompleted = currentUser.getWaitCompleted();
        if (ObjectUtils.isEmpty(waitCompleted)) {
            return;
        }
        String[] actions = waitCompleted.split(ConstantDict.Separator.comma);
        LinkedHashSet<String> actionSet = new LinkedHashSet<>(Arrays.asList(actions));
        if (actionSet.size() > 0) {
            log.debug("房间号:{},通知用户:{},更新事件:{}", code, currentUser.getUsername(), actionSet);
            List<MessageContent<MessageToClient>> callMessageList = MessageContentFactory.
                    init(code, MessageType.ACTION.getType(), currentUser.getUserId(), MessageNoticeEnum.CURRENT)
                    .multi(MKey.exeActionUid, currentUser.getUserId(),
                            MKey.actionSet, actionSet,
                            MKey.type, MahjongActionEnum.REFRESH_ACTION.getAction())
                    .send().getMessageList();
            RoomInfoTL.addMessageToClient(callMessageList, sleep);
        }
    }


    public GameRuMahjongLogs checkUserPassAction(List<GameRuMahjongLogs> logs, MahjongActionEnum actionEnum) {
        if (ObjectUtils.isEmpty(logs)) {
            return null;
        }
        // 用户是否有max
        Optional<GameRuMahjongLogs> userMaxPass = logs.stream().filter(item -> item.getType().equals(ConstantDict.MahjongLogType.USER) && item.getAction().equals(MahjongActionEnum.PASS.getAction())).max(Comparator.comparing(GameRuMahjongLogs::getId));
        // 服务器是否下发了  指定的 指令
        Optional<GameRuMahjongLogs> actionOption = logs.stream().filter(item -> item.getType().equals(ConstantDict.MahjongLogType.ROOM) && item.getAction().equals(actionEnum.getAction())).max(Comparator.comparing(GameRuMahjongLogs::getId));
        if (!userMaxPass.isPresent()) {
            return null;
        }
        if (!actionOption.isPresent()) {
            return null;
        }
        // 要确保  pass 大于  指定的事件  才能表示 这一轮 用户 过了
        int comparisonResult = userMaxPass.get().getId().compareTo(actionOption.get().getId());
        if (comparisonResult > 0) {
            return actionOption.get();
        }
        return null;
    }
}
